<template>
  <div class="differential-testing">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>测试配置</span>
      </div>
      <el-form>
        <!-- <el-form-item label="选择mode">
          <el-radio-group v-model="form.mode">
            <el-radio label="solidity">Solidity</el-radio>
            <el-radio label="solidity">Bytecode</el-radio>
          </el-radio-group>
        </el-form-item> -->

        <!-- EVM选取部分 -->
        <el-form-item label="EVM选取">
          <el-card class="evm-selection-box">
            <el-row>
              <el-col :span="12">
                <el-checkbox-group v-model="form.evmList">
                  <el-checkbox label="Geth">Geth (执行客户端, Golang)</el-checkbox>
                  <el-checkbox label="SealEVM">SealEVM (自定义EVM, Golang)</el-checkbox>
                  <el-checkbox label="Besu">Besu (执行客户端, Java)</el-checkbox>
                  <el-checkbox label="ethereumjs/evm">ethereumjs/evm (独立EVM, Typescript)</el-checkbox>
                </el-checkbox-group>
              </el-col>
              <el-col :span="12">
                <el-checkbox-group v-model="form.evmList">
                  <el-checkbox label="Nethermind">Nethermind (执行客户端, C#)</el-checkbox>
                  <el-checkbox label="revm">revm (独立EVM, Rust)</el-checkbox>
                  <el-checkbox label="Py-EVM">Py-EVM (独立EVM, Python)</el-checkbox>
                  <el-checkbox label="evmone">evmone (独立EVM, C++)</el-checkbox>
                </el-checkbox-group>
              </el-col>
            </el-row>
          </el-card>
        </el-form-item>

        <!-- 测试用例输入框 -->
        <el-form-item label="输入字节码测试用例">
          <el-input v-model="form.testCase" type="textarea" placeholder="在此输入生成的字节码测试用例" />
        </el-form-item>

        <el-form-item label="测试次数">
          <el-input-number v-model="form.testTimes" :min="1" :max="100" />
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="startTest">开始测试</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 测试进度展示 -->
    <el-card class="box-card" style="margin-top: 20px;">
      <div slot="header" class="clearfix">
        <span>测试进度</span>
      </div>
      <el-progress :percentage="progress" status="active" />
    </el-card>

    <!-- 覆盖率展示 -->
    <el-card class="box-card" style="margin-top: 20px;">
      <div slot="header" class="clearfix">
        <span>测试覆盖率</span>
      </div>
      <el-row>
        <el-col :span="12" class="coverage-item">
          <h4>函数覆盖率</h4>
          <el-tooltip :content="`${functionCoverage}%`" placement="top">
            <el-progress
              type="circle"
              :percentage="functionCoverage"
              :color="getCoverageColor(functionCoverage)"
            />
          </el-tooltip>
        </el-col>
        <el-col :span="12" class="coverage-item">
          <h4>包覆盖率</h4>
          <el-tooltip :content="`${packageCoverage}%`" placement="top">
            <el-progress
              type="circle"
              :percentage="packageCoverage"
              :color="getCoverageColor(packageCoverage)"
            />
          </el-tooltip>
        </el-col>
      </el-row>
    </el-card>

    <!-- 差分测试不一致性结果展示 -->
    <el-card class="box-card" style="margin-top: 20px;">
      <div slot="header" class="clearfix">
        <span>测试结果</span>
      </div>

      <div v-if="testResult">
        <el-table :data="testResult" style="width: 100%">
          <el-table-column prop="evm" label="EVM实现" width="180" />
          <el-table-column prop="result" label="测试结果" />
          <el-table-column prop="gasUsed" label="Gas消耗" width="120" />
          <el-table-column prop="stackState" label="栈状态" width="150" />
          <el-table-column prop="storageState" label="存储状态" width="150" />
        </el-table>
      </div>

      <div v-else>
        <p>尚未开始测试或无测试结果</p>
      </div>
    </el-card>

    <!-- 不一致性根本原因定位 -->
    <el-card class="box-card" style="margin-top: 20px;">
      <div slot="header" class="clearfix">
        <span>不一致性根本原因定位</span>
      </div>
      <div v-if="inconsistencyDetails">
        <el-alert
          title="发现不一致"
          type="error"
          description="详细分析结果如下"
          show-icon
        />
        <el-table :data="inconsistencyDetails" style="width: 100%">
          <el-table-column prop="opcode" label="操作码" width="150" />
          <el-table-column prop="reason" label="不一致原因" />
        </el-table>
      </div>
      <div v-else>
        <p>尚未发现不一致性或无数据</p>
      </div>
    </el-card>
  </div>
</template>

<script>
export default {
  data() {
    return {
      form: {
        mode: 'solidity', // 默认solidity
        evmList: ['Geth'], // 默认选择一个EVM实现
        testTimes: 1 // 默认测试次数
      },
      progress: 0, // 测试进度
      functionCoverage: '', // 函数覆盖率
      packageCoverage: '', // 包覆盖率
      testResult: null, // 测试结果
      inconsistencyDetails: null // 不一致性详情
    }
  },
  methods: {
    startTest() {
      this.progress = 0 // 初始化进度
      this.updateCoverage(this.form.testTimes)
      // 模拟测试进度
      const interval = setInterval(() => {
        if (this.progress >= 100) {
          clearInterval(interval)
          this.fetchTestResult()
          this.checkForInconsistencies()
        } else {
          this.progress += 30
        }
      }, 50)
    },
    updateCoverage(testCount) {
      const coverageData = {
        1: { functionCoverage: 35.20, packageCoverage: 21.42 },
        2: { functionCoverage: 37.90, packageCoverage: 35.14 },
        3: { functionCoverage: 38.00, packageCoverage: 35.22 },
        4: { functionCoverage: 38.55, packageCoverage: 35.65 },
        5: { functionCoverage: 39.29, packageCoverage: 35.80 },
        6: { functionCoverage: 40.40, packageCoverage: 35.86 },
        7: { functionCoverage: 43.20, packageCoverage: 53.06 },
        8: { functionCoverage: 49.80, packageCoverage: 65.79 },
        9: { functionCoverage: 52.40, packageCoverage: 75.78 },
        10: { functionCoverage: 54.40, packageCoverage: 91.85 }
      }
      if (coverageData[testCount]) {
        this.functionCoverage = coverageData[testCount].functionCoverage
        this.packageCoverage = coverageData[testCount].packageCoverage
      }
    },
    fetchTestResult() {
      // 根据输入的字节码示例生成差分测试结果
      const bytecode = this.form.testCase

      if (bytecode === '7324d82e387fcccb6c675d75947bf2e8e09fbea57d3b60005260406000f3') {
        this.testResult = [
          {
            evm: 'Geth',
            result: '通过',
            gasUsed: '0xa3d', // Geth的Gas消耗
            stackState: '正常',
            storageState: '一致',
            output: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
          },
          {
            evm: 'SealEVM',
            result: '通过',
            gasUsed: '0x6', // SealEVM的Gas消耗
            stackState: '正常',
            storageState: '一致',
            output: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
          }
        ]
        this.inconsistencyDetails = [
          { opcode: 'EXTCODESIZE', reason: '外部合约调用失败，未找到合约代码' },
          { opcode: 'PUSH20', reason: 'Gas消耗差异' },
          { opcode: 'RETURN', reason: 'Geth返回有效输出，SealEVM未返回' }
        ]
      } else if (bytecode === '4860005260406000f3') {
        // 处理字节码为 4860005260406000f3 的逻辑
        this.testResult = [
          {
            evm: 'Geth',
            result: '失败',
            gasUsed: '0x14',
            stackState: '异常',
            storageState: '不一致',
            error: '执行操作码 BASEFEE 返回值不正确，未采用 genesis 中设置的值'
          },
          {
            evm: 'SealEVM',
            result: '失败',
            gasUsed: '0x0',
            stackState: '未知',
            storageState: '未知',
            error: '执行操作码 BASEFEE 失败'
          }
        ]
        this.inconsistencyDetails = [
          { opcode: 'BASEFEE', reason: '返回值不正确，未采用 genesis 中设置的值' },
          { opcode: 'MSTORE', reason: '内存状态不同' }
        ]
      } else {
        // 其他字节码的处理
        this.testResult = [
          {
            evm: 'Geth',
            result: '失败',
            gasUsed: '0x0', // 示例Gas消耗
            stackState: '异常',
            storageState: '不一致',
            error: '示例错误信息'
          },
          {
            evm: 'SealEVM',
            result: '通过',
            gasUsed: '0x0', // 示例Gas消耗
            stackState: '正常',
            storageState: '一致',
            output: '示例输出'
          }
        ]
        this.inconsistencyDetails = [
          { opcode: '示例操作码', reason: '示例不一致原因' }
        ]
      }
    },
    checkForInconsistencies() {
      // 模拟不一致性分析
      this.inconsistencyDetails = [
        { opcode: 'EXTCODESIZE', reason: '堆栈处理实现出错' },
        { opcode: 'PUSH20', reason: 'Gas消耗处理实现出错' },
        { opcode: 'RETURN', reason: '操作码执行实现出错' }
      ]
    },

    getCoverageColor(percentage) {
      if (percentage >= 96) {
        return '#67C23A' // 绿色表示高覆盖率
      } else if (percentage >= 95) {
        return '#E6A23C' // 橙色表示中等覆盖率
      } else {
        return '#F56C6C' // 红色表示低覆盖率
      }
    }
  }
}
</script>

<style scoped>
.differential-testing {
  padding: 40px;
  background-color: #f0f4f7;
  border-radius: 8px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.el-table {
  margin-top: 20px;
  background-color: #ffffff;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.box-card {
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  margin-bottom: 20px;
}

.evm-selection-box {
  padding: 20px;
  background-color: #f9f9f9;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.el-button {
  border-radius: 4px;
  font-weight: bold;
}

.el-form-item label {
  font-weight: bold;
  color: #333;
}

.el-input__inner {
  border-radius: 4px;
  padding: 10px;
  border: 1px solid #d1d5db;
  transition: border-color 0.3s ease;
}

.el-input__inner:focus {
  border-color: #409eff;
  box-shadow: 0 0 5px rgba(64, 158, 255, 0.5);
}

.coverage-item {
  text-align: center;
  margin-top: 20px;
  position: relative;
}

.coverage-item h4 {
  font-weight: bold;
  color: #606266;
  margin-bottom: 10px;
}

.el-progress-circle {
  max-width: 140px;
  margin: auto;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
  position: relative;
}

.el-tooltip {
  font-size: 14px;
}

.el-progress__text {
  font-size: 22px;
  font-weight: bold;
  color: #fff;
  text-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
}

/* New styles for a cooler look */
/* .coverage-item .el-progress {
  background: conic-gradient(
    #67C23A 0% calc(var(--percentage) * 1%),
    #E6A23C calc(var(--percentage) * 1%) calc(var(--percentage) * 2%),
    #F56C6C calc(var(--percentage) * 2%) 100%
  );
  animation: spin 15s linear infinite;
  transition: background 10s ease;
} */

/* .coverage-item:hover .el-progress {
  animation: spin-hover 10s linear infinite;
} */

/* @keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

@keyframes spin-hover {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(720deg);
  }
} */

.el-dialog__header {
  background-color: #f0f4f7;
  border-bottom: 1px solid #ebeef5;
}

.el-dialog__body {
  padding: 20px;
}

.el-alert {
  margin-bottom: 20px;
}
</style>
